import dicomParser from "dicom-parser";
import canvas from "canvas";
import getVOILUT from "./getVOILUT";


/**
 * 转化dcm为image,有一定的误差，建议测试环境使用，正式环境使用后台数据
 * @param {} image 
 * @returns 
 */
export function dcmToImg(image) {
  const dicomFileAsBuffer = new Uint8Array(image.data.byteArray.buffer);
  let dataSet = dicomParser.parseDicom(dicomFileAsBuffer);
  let tags;
  try {
    tags = dicomParser.explicitDataSetToJS(dataSet);
  } catch (e) {
    console.log("提取tag失败，使用图像数据");
    tags = null;
  }
  const w = parseInt(
    tags && tags["x00280011"] ? tags["x00280011"] : image.width
  ); //图片宽度
  const h = parseInt(
    tags && tags["x00280010"] ? tags["x00280010"] : image.height
  ); //图片高度
  let invert =
    tags && tags["x00280004"]
      ? tags["x00280004"] === "MONOCHROME1"
        ? true
        : false
      : image.invert; //图像是否被反转显示
  let windowCenter = parseInt(
    tags && tags["x00281050"] ? tags["x00281050"] : image.windowCenter
  ); //窗口中心
  let windowWidth = parseInt(
    tags && tags["x00281051"] ? tags["x00281051"] : image.windowWidth
  ); //窗口宽度
  let pixelData = dataSet.elements.x7fe00010 || image.getPixelData();
  const pixelDataBuffer = dicomParser.sharedCopy(
    dicomFileAsBuffer,
    pixelData.dataOffset,
    pixelData.length
  );
  //生成PNG
  const cv = canvas.createCanvas(w / 4, h / 4); //创建画布
  let ctx = cv.getContext("2d"); //灰度图
  let uint16 = new Uint16Array(
    pixelDataBuffer.buffer,
    pixelDataBuffer.byteOffset,
    pixelDataBuffer.byteLength / Uint16Array.BYTES_PER_ELEMENT
  ); //获取uint16的像素数组
  let voiLUT;
  let lut = _getLut(uint16, windowWidth, windowCenter, invert, voiLUT); //获取灰度数组
  //替换对应像素点为灰度
  //计算uint8应有的长度
  const u8shouldLength = w * h * 4;
  let uint8 = new Uint8ClampedArray(u8shouldLength);
  for (let i = 0; i < u8shouldLength; i++) {
    if (i > uint16.length) {
      uint8[i] = 0;
    } else { 
      uint8[i] = lut.lutArray[uint16[i]];
    }
  }
  let imageData = canvas.createImageData(uint8, w, h);
  ctx.putImageData(imageData, 0, 0);
  let base64 = cv.toDataURL("image/png");
  return base64;
}

const _getLut = (data, windowWidth, windowCenter, invert, voiLUT) => {
  let minPixelValue = 0;
  let maxPixelValue = 0;
  for (let i = 0, len = data.length; i < len; i++) {
    if (minPixelValue > data[i]) {
      minPixelValue = data[i];
    }
    if (maxPixelValue < data[i]) {
      maxPixelValue = data[i];
    }
  }
  let offset = Math.min(minPixelValue, 0);
  let lutArray = new Uint8ClampedArray(maxPixelValue - offset + 1);
  const vlutfn = getVOILUT(windowWidth, windowCenter, voiLUT, true);
  if (invert === true) {
    for (
      let storedValue = minPixelValue;
      storedValue <= maxPixelValue;
      storedValue++
    ) {
      lutArray[storedValue + -offset] = 255 - vlutfn(storedValue);
    }
  } else {
    for (
      let storedValue = minPixelValue;
      storedValue <= maxPixelValue;
      storedValue++
    ) {
      lutArray[storedValue + -offset] = vlutfn(storedValue);
    }
  }
  return {
    minPixelValue: minPixelValue,
    maxPixelValue: maxPixelValue,
    lutArray: lutArray,
  };
};
